iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0
自我挑戰組

寫程式帶給我的無形快樂系列 第 21

吃下 Regular Expressions 翻譯年糕 (環顧四周)

  • 分享至 

  • xImage
  •  

有些時候想要匹配的規則,會想知道該位置的前後字元是否有符合我們想要的規則

有種像是告訴 Regex Engine 説:
你先幫我找到 X,找到後再幫我看看它的前面有沒有 Y,或是它的後面有沒有 Z

這樣環顧四周的行為分成 LookaheadLookbehind 兩種


Lookahead

網路上翻作 先行斷言

X(?=Y) 代表要找 X,而且後面要跟著 Y 的我才要

Regex Engine 運作時,它會先找到 X的位置,接著再檢查是否有 Y 緊跟著

也可以用 Negative Lookahead,代表後面不要接著某某字元,例如: (?!foo)


Lookbehind

網路上翻作 後行斷言

注意: 在非 V8 Engine 的瀏覽器,像是 Safari IE 是不支援 Lookbehind 的!!

Lookahead 類似,Lookbehind 會幫我們回溯一個字元看

例如 (?<=Y)X 代表幫我找到 X,但X 左側要是 Y
一樣也可以使用 Negative Lookbehind,例如: (?<!foo)


練習

範例取自 Lookahead and lookbehind

試著找出字串中不為負數的整數出來

let regexp = /your regexp/g;

let str = "0 12 -5 123 -18";

alert( str.match(regexp) ); // 0, 12, 123

找出不為負數的規則是:

  1. 找出數字 (最大不限幾位數,至少為個位數)
  2. 且該數字的左側 (Lookbehind) 不為負號

翻譯年糕:

目標要找出 \d 數字,而且數字的數量不設上限+,至少出現一次以上
數字的左側不得為負號 (?<!-)

第一次可能會這樣寫 /(?<!-)\d+/g
會發現 -188 也被匹配到
因為 『 數字的左側不得為負號 』這個規則,應該是指數字的第一位數左側不為負號

可以改成 /(?<![-\d])\d+/g

或是我會改成 /(?<!-)\b\d+/g 多加一個 \b ,數字開頭要為單詞邊界


小結

pattern 是從文本的左至右去做匹配

往右側的下一個字元看 --> Lookahead
往左側的上一個字元看 --> Lookbehind

Pattern 說明 Match 例子
X(?=Y) X 後面接著 Y XY
X(?!Y) X 後面不要接著 Y XZ
(?<=Y)X X 前面是 Y YX
(?<!Y)X X 前面不是 Y ZX

以上匹配到的都是 X, 並不包含 () 內的內容

() 中寫的 Lookahead或是 Lookbehind 是不佔位不佔位的!

預告下一篇,迎接 Regular Expressions 年糕最後一口, Regex Engine


上一篇
吃下 Regular Expressions 翻譯年糕 (位置)
下一篇
吃下 Regular Expressions 翻譯年糕 (Regex Engine)
系列文
寫程式帶給我的無形快樂30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言